"""Command-line interface for ChatWithRepository."""

import os
import sys
from pathlib import Path
from typing import Optional

import click
from rich.console import Console
from rich.markdown import Markdown
from rich.table import Table
from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, TextColumn

from .config import Config
from .github_downloader import GitHubDownloader
from .query_engine import QueryEngine
from .rag_indexer import RAGIndexer

console = Console()

@click.group()
@click.version_option(version="0.1.0", prog_name="chat-with-repo")
@click.pass_context
def cli(ctx):
    """ChatWithRepository - Natural language querying for GitHub repositories."""
    ctx.ensure_object(dict)
    
    # Validate configuration
    try:
        Config.validate()
    except ValueError as e:
        console.print(f"[red]Configuration error: {e}[/red]")
        console.print("Please set your KIMI_API_KEY in the .env file")
        console.print("Run: python main.py setup")
        sys.exit(1)

@cli.command()
@click.argument('repo_url')
@click.option('--branch', default='main', help='Branch to checkout')
@click.option('--force-reindex', is_flag=True, help='Force reindex even if already indexed')
def add(repo_url: str, branch: str, force_reindex: bool):
    """Add a GitHub repository for querying."""
    
    downloader = GitHubDownloader()
    indexer = RAGIndexer()
    
    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        console=console,
    ) as progress:
        
        # Download repository
        download_task = progress.add_task("Downloading repository...", total=None)
        try:
            repo_path = downloader.download_repository(repo_url, branch)
            progress.update(download_task, completed=True)
        except Exception as e:
            console.print(f"[red]Failed to download repository: {e}[/red]")
            return
        
        # Check if already indexed
        if not force_reindex:
            stats = indexer.get_repository_stats(repo_url)
            if stats["indexed"]:
                console.print(f"[yellow]Repository already indexed ({stats['chunks']} chunks). Use --force-reindex to reindex.[/yellow]")
                return
        
        # Index repository
        index_task = progress.add_task("Indexing repository...", total=None)
        try:
            chunk_count = indexer.index_repository(repo_path, repo_url)
            progress.update(index_task, completed=True)
            console.print(f"[green]Successfully indexed {chunk_count} code chunks[/green]")
        except Exception as e:
            console.print(f"[red]Failed to index repository: {e}[/red]")

@cli.command()
@click.argument('query')
@click.option('--repo', help='Repository URL to query')
@click.option('--markdown/--no-markdown', default=True, help='Format output as markdown')
def query(query: str, repo: Optional[str], markdown: bool):
    """Query a repository using natural language."""
    
    engine = QueryEngine()
    
    try:
        response = engine.query_repository(query, repo)
        
        if markdown:
            console.print(Markdown(response))
        else:
            console.print(response)
            
    except Exception as e:
        console.print(f"[red]Query failed: {e}[/red]")

@cli.command()
@click.argument('repo_url')
def remove(repo_url: str):
    """Remove a repository from the index."""
    
    indexer = RAGIndexer()
    downloader = GitHubDownloader()
    
    # Remove from index
    removed_from_index = indexer.clear_repository(repo_url)
    
    # Remove local files
    removed_locally = downloader.remove_repository(repo_url)
    
    if removed_from_index or removed_locally:
        console.print(f"[green]Successfully removed repository: {repo_url}[/green]")
    else:
        console.print(f"[yellow]Repository not found: {repo_url}[/yellow]")

@cli.command()
def list():
    """List all indexed repositories."""
    
    indexer = RAGIndexer()
    downloader = GitHubDownloader()
    
    # Get local repositories
    local_repos = downloader.list_repositories()
    
    if not local_repos:
        console.print("[yellow]No repositories found. Use 'add' command to add repositories.[/yellow]")
        return
    
    # Create table
    table = Table(title="Indexed Repositories")
    table.add_column("Repository", style="cyan")
    table.add_column("Status", style="green")
    table.add_column("Chunks", style="blue")
    
    for repo_name in local_repos:
        repo_path = Path(Config.REPOS_DIR) / repo_name
        stats = indexer.get_repository_stats(str(repo_path))
        
        status = "✅ Indexed" if stats["indexed"] else "❌ Not Indexed"
        chunks = str(stats["chunks"]) if stats["indexed"] else "-"
        
        table.add_row(repo_name, status, chunks)
    
    console.print(table)

@cli.command()
@click.argument('function_name')
@click.option('--repo', help='Repository URL to search in')
def explain(function_name: str, repo: Optional[str]):
    """Explain what a specific function does."""
    
    engine = QueryEngine()
    
    try:
        response = engine.explain_function(function_name, repo)
        console.print(Markdown(response))
    except Exception as e:
        console.print(f"[red]Failed to explain function: {e}[/red]")

@cli.command()
@click.argument('module_name')
@click.option('--repo', help='Repository URL to search in')
def usage(module_name: str, repo: Optional[str]):
    """Find usage of a specific module."""
    
    engine = QueryEngine()
    
    try:
        response = engine.find_module_usage(module_name, repo)
        console.print(Markdown(response))
    except Exception as e:
        console.print(f"[red]Failed to find module usage: {e}[/red]")

@cli.command()
@click.option('--repo', help='Repository URL to search in')
@click.argument('error_type', required=False)
def errors(error_type: Optional[str] = None, repo: Optional[str] = None):
    """Find error handling examples."""
    
    engine = QueryEngine()
    
    try:
        response = engine.find_error_examples(error_type or "", repo)
        console.print(Markdown(response))
    except Exception as e:
        console.print(f"[red]Failed to find error examples: {e}[/red]")

@cli.command()
def interactive():
    """Start interactive mode."""
    
    engine = QueryEngine()
    
    console.print(Panel.fit(
        "[bold blue]ChatWithRepository Interactive Mode[/bold blue]\n"
        "Type your questions about the indexed repositories.\n"
        "Commands: 'exit', 'quit', 'help'",
        border_style="blue"
    ))
    
    while True:
        try:
            query = console.input("\n[bold green]Query: [/bold green]").strip()
            
            if query.lower() in ['exit', 'quit']:
                console.print("Goodbye!")
                break
            
            if query.lower() == 'help':
                console.print("\n[bold]Available commands:[/bold]")
                console.print("- Ask any question about the indexed code")
                console.print("- 'exit' or 'quit' to leave")
                console.print("- 'help' to show this message")
                continue
            
            if not query:
                continue
            
            response = engine.query_repository(query)
            console.print(Markdown(response))
            
        except KeyboardInterrupt:
            console.print("\nGoodbye!")
            break
        except Exception as e:
            console.print(f"[red]Error: {e}[/red]")

@cli.command()
def setup():
    """Setup the application (create .env file)."""
    
    env_file = Path(".env")
    
    if env_file.exists():
        console.print("[yellow].env file already exists.[/yellow]")
        overwrite = click.confirm("Overwrite?")
        if not overwrite:
            return
    
    kimi_key = click.prompt("Enter your KIMI API key", hide_input=True)
    github_token = click.prompt("Enter your GitHub token (optional)", hide_input=True, default="")
    
    env_content = f"KIMI_API_KEY={kimi_key}\n"
    if github_token:
        env_content += f"GITHUB_TOKEN={github_token}\n"
    env_content += f"KIMI_API_BASE=https://api.moonshot.cn/v1\n"
    
    env_file.write_text(env_content)
    console.print("[green]Configuration saved to .env[/green]")

@cli.command()
def status():
    """Show application status."""
    
    table = Table(title="Application Status")
    table.add_column("Component", style="cyan")
    table.add_column("Status", style="green")
    
    # Check KIMI API key
    kimi_status = "✅ Set" if Config.KIMI_API_KEY else "❌ Missing"
    table.add_row("KIMI API Key", kimi_status)
    
    # Check GitHub token
    github_status = "✅ Set" if Config.GITHUB_TOKEN else "⚠️  Optional"
    table.add_row("GitHub Token", github_status)
    
    # Check directories
    repos_dir = Path(Config.REPOS_DIR)
    repos_status = "✅ Created" if repos_dir.exists() else "❌ Missing"
    table.add_row("Repositories Directory", repos_status)
    
    chroma_dir = Path(Config.CHROMA_PERSIST_DIR)
    chroma_status = "✅ Created" if chroma_dir.exists() else "❌ Missing"
    table.add_row("Vector Database", chroma_status)
    
    console.print(table)

if __name__ == "__main__":
    cli()